package com.functest.jpwise.deprecated;

import com.functest.jpwise.core.ParameterValue;

import java.util.*;

/** Represents a factory that creates all possible parameter combinations for a jUnit test.
 * Using such a factory ensures that all possible values of each parameter get tested. Note that when a test only takes
 * one or two parameters, this is equivalent to all-values or all-pairs testing, respectively. For tests with more
 * parameters, sometimes this can produce a huge number of test-cases. This approach is not recommended in those cases
 * unless each test case is extremely fast and any test failure would have extremely serious consequences.
 * @author Jeremy Reeder
 * @version 2011-11-15
 * @since 2011-10-28 */
public class AllCombinationsParameterFactory extends ParameterFactory {
	private static List<List<ParameterValue>> cartesianProductOfIdLists(List<Set<ParameterValue>> inputListOfIdSets) {
		List<List<ParameterValue>> possiblyIncompleteResult = null, moreCompleteResult = new ArrayList<>();
		moreCompleteResult.add(new ArrayList<ParameterValue>());
		for (Set<ParameterValue> idSet : inputListOfIdSets) {
			possiblyIncompleteResult = new ArrayList<>(moreCompleteResult);
			for (List<ParameterValue> possiblyIncompleteCombination : possiblyIncompleteResult)
				for (ParameterValue inputId : idSet) {
					moreCompleteResult.remove(possiblyIncompleteCombination);
					final List<ParameterValue> moreCompleteCombination = new ArrayList<>(possiblyIncompleteCombination);
					moreCompleteCombination.add(inputId);
					moreCompleteResult.add(moreCompleteCombination);
				}
		}
		return moreCompleteResult;
	}
	protected List<ParameterValue[]> createListOfParameterIdCombinations() {
		final List<ParameterValue[]> listOfParameterIdCombinations;
		final List<List<ParameterValue>> listOfParameterIdLists = cartesianProductOfIdLists(orderedListOfParameterIdSets);
		listOfParameterIdCombinations = new ArrayList<ParameterValue[]>();
		for (List<ParameterValue> parameterIdList : listOfParameterIdLists) {
			final ParameterValue[] parameterIds = parameterIdList.toArray(new ParameterValue[0]);
			listOfParameterIdCombinations.add(parameterIds);
		}
		return listOfParameterIdCombinations;
	}
}
